﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
using Doo.DataView;
using Doo.Scripts;

namespace Doo.Controls
{
    /*
     * 使用指定的模版进行
     */

    [ToolboxData("<{0}:ListView runat=server></{0}:ListView>")]
    [ParseChildren(ChildrenAsProperties = true)]
    public class ListView : DataView.DataViewBase, Doo.Scripts.IClientEvent<ListView.ListViewClientEvents>
    {
        const string _ScriptName = "Doo.WebUI.DataView.ListView.script.js";

        #region 基本属性设置

        /// <summary>
        /// 类型
        /// </summary>
        public override string ClientControlType
        {
            get
            {
                return "Doo.ListView";
            }
        }

        /// <summary>
        /// 资源名
        /// </summary>
        public override string ScriptResourceName
        {
            get
            {
                return _ScriptName;
            }
        }

        #endregion

        #region 客户端事件

        public class ListViewClientEvents : DataViewClientEvents
        {
        }

        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ListViewClientEvents ClientEvents { get; set; }

        #endregion

        #region 模板属性设置
        /// <summary>
        /// 引用模版所在的XML地址，但内部模版优先
        /// </summary>
        public string TemplateFile { get; set; }

        /// <summary>
        /// 是否将外部引用的模版内置
        /// </summary>
        public bool InlineTemplate { get; set; }

        /// <summary>
        /// 根模板ID
        /// </summary>
        public string RootTemplateId { get; set; }

        //内部模版
        [Category("Behavior"),
        Description("选择参数"),
        DesignerSerializationVisibility(
        DesignerSerializationVisibility.Content),
        PersistenceMode(PersistenceMode.InnerProperty)
        ]
        public List<Template> Templates { get; set; }

        /// <summary>
        /// 保存为外部模版，不能和TemplateFile和InlineTemplate同时使用避免冲突
        /// </summary>
        public bool ExportTemplate { get; set; }

        /// <summary>
        /// 唯一文件名
        /// </summary>
        public string ExportUniqueName { get; set; }

        #endregion

        #region 根据InlineMode返回不同的Tag
        public bool InlineMode { get; set; }

        protected override string TagName
        {
            get
            {
                return InlineMode ? "span" : "div";
            }
        }

        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return InlineMode ? HtmlTextWriterTag.Span : HtmlTextWriterTag.Div;
            }
        }
        #endregion

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if (this.ClientEvents != null) this.ClientEvents.Init(Page, Parent);
        }

        static int globalVersion = 0;

        protected override void SetScriptDescriptor(ScriptControlDescriptor descriptor)
        {
            base.SetScriptDescriptor(descriptor);

            if (this.Templates != null && this.Templates.Count > 0)
            {
                if (ExportTemplate)
                {
                    #region 处理导出
                    //保存到外部区域，随着所在控件的文件改变而变
                    //缓存：键Doo.ExTpl.AppSourcePath.UniqueName 值：GlobalVersion
                    string ck = string.Format("Doo.ExTpl.{0}.{1}", TemplateControl.AppRelativeVirtualPath, ExportUniqueName);
                    string v = Page.Cache[ck] as string;
                    string fn = Doo.Config.DooSetting.ExportTemplatePath + ExportUniqueName + ".xml";
                    if (v == null)
                    {
                        var xmldoc = System.Xml.Linq.XDocument.Parse("<?xml version=\"1.0\" encoding=\"utf-8\" ?> <root></root>");
                        var root = xmldoc.Root;
                        foreach (Template tpl in this.Templates)
                        {
                            System.Xml.Linq.XElement xe = new System.Xml.Linq.XElement("template");
                            xe.SetAttributeValue("id", tpl.ID);
                            xe.SetValue(tpl.Text);
                            root.Add(xe);
                        }
                        xmldoc.Save(Page.Request.MapPath(fn));
                        v = (++globalVersion).ToString();
                        Page.Cache.Insert(ck, v, new System.Web.Caching.CacheDependency(Page.Server.MapPath(TemplateControl.AppRelativeVirtualPath)));
                    }

                    descriptor.AddProperty("tplurl", ResolveClientUrl(fn) + "?" + v);
                    #endregion
                }
                else
                {
                    var tpls = new Hashtable();
                    foreach (Template tpl in this.Templates)
                    {
                        tpls.Add(tpl.ID, tpl.Text);
                    }
                    descriptor.AddProperty("tpls", tpls);
                }
            }
            else if (InlineTemplate)
            {//得到外部模版地址，必须可读
                #region 处理导入
                string filepath = Page.Server.MapPath(TemplateFile);

                var xmldoc = System.Xml.Linq.XDocument.Load(filepath);
                var its = xmldoc.Root.Elements("template");
                var tpls = new Hashtable();
                if (its != null && its.Any())
                {
                    foreach (var it in its)
                    {
                        tpls.Add(it.Attribute("id").Value, it.Value);
                    }
                }
                if (tpls.Count > 0) descriptor.AddProperty("tpls", tpls);
                #endregion
            }
            else if (!string.IsNullOrEmpty(this.TemplateFile))
            {//指定了外部模板地址
                descriptor.AddProperty("tplurl", ResolveClientUrl(TemplateFile));
            }

            if (!string.IsNullOrEmpty(RootTemplateId))
            {
                descriptor.AddProperty("roottplid", RootTemplateId);
            }
        }

    }
}
